package com.itcam.pro01;

import java.util.concurrent.*;

/**
 * @author : Cammy.Wu
 * Description : 
 */

public class CompletableFutureDemo04Use {

    public static void main(String[] args) {
        // 创建一个固定大小为3的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        // 使用 CompletableFuture 的 supplyAsync 方法异步执行任务
        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            // 打印当前线程的名称，表示进入任务
            System.out.println(Thread.currentThread().getName() + "---come in");
            // 生成一个 0 到 9 之间的随机整数
            int result = ThreadLocalRandom.current().nextInt(10);
            try {
                // 线程休眠 1 秒
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                // 捕获中断异常并打印堆栈信息
                e.printStackTrace();
            }
            // 模拟产生异常
            if (result > 5) {
                int i = 10 / 0;
            }
            // 打印结果
            System.out.println("----------1秒钟后出结果" + result);
            // 返回结果
            return result;
        }, executorService)
        // 当任务完成时，进行回调处理
        .whenComplete((v,e)->{
            // 如果没有异常
            if(e==null){
                // 打印计算完成信息和结果
                System.out.println("计算完成 更新系统" + v);
            }
        })
        // 当任务出现异常时，进行异常处理
        .exceptionally(e->{
            // 打印异常堆栈信息
            e.printStackTrace();
            // 打印异常情况
            System.out.println("异常情况：" + e.getCause() + " " + e.getMessage());
            // 返回 null
            return null;
        });
        // 主线程继续执行其他任务
        System.out.println(Thread.currentThread().getName() + "先去完成其他任务");
        // 关闭线程池
        executorService.shutdown();
    }

    /**
     * todo:    CompletableFuture优点：
     *              ● 异步任务结束时，会自动回调某个对象的方法
     *              ● 主线程设置好回调后，不用关心异步任务的执行，异步任务之间可以顺序执行
     *              ● 异步任务出错时，会自动回调某个对象的方法
     */

}
